﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
using Pfz.Extensions;

namespace Pfz.WpfControls
{
	/// <summary>
	/// Wrap grid that allow headers to be set.
	/// </summary>
	[ContentProperty("Children")]
	public sealed class HeadedWrapGrid:
		UserControl
	{
		private ObservableCollection<WrapGridHeader> _headers = new ObservableCollection<WrapGridHeader>();
		private Grid _header = new Grid();
		internal WrapGrid _grid = new WrapGrid();
		internal ScrollViewer _scrollViewer = new ScrollViewer();

		/// <summary>
		/// Creates a new instance.
		/// </summary>
		public HeadedWrapGrid()
		{
			_headers.CollectionChanged += _headers_CollectionChanged;

			DockPanel content = new DockPanel();
			content.LastChildFill = true;

			_scrollViewer.Content = _grid;
			_scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;

			var contentChildren = content.Children;
			DockPanel.SetDock(_header, Dock.Top);
			contentChildren.Add(_header);
			contentChildren.Add(_scrollViewer);

			Content = content;
		}

		private double _splitterWidth = 2;
		/// <summary>
		/// Gets or sets the size of the splitter.
		/// </summary>
		public double SplitterWidth
		{
			get
			{
				return _splitterWidth;
			}
			set
			{
				_splitterWidth = value;
			}
		}

		/// <summary>
		/// Gets or sets the Height of the header.
		/// </summary>
		public double HeaderHeight
		{
			get
			{
				return _header.Height;
			}
			set
			{
				_header.Height = value;
			}
		}

		/// <summary>
		/// Gets the Headers collection.
		/// </summary>
		public ObservableCollection<WrapGridHeader> Headers
		{
			get
			{
				return _headers;
			}
		}

		private void _headers_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
		{
			this.Dispatcher.BeginInvokeOnce(new Action(_Recreate));
		}

		/// <summary>
		/// Resizes the last item.
		/// </summary>
		protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
		{
			base.OnRenderSizeChanged(sizeInfo);

			if (_header.Children.Count > 0)
				((WrapGridHeader)_header.Children[_header.Children.Count-1])._Resize();
		}

		private void _Recreate()
		{
			var columnDefinitions = _header.ColumnDefinitions;
			columnDefinitions.Clear();

			var headerChildren = _header.Children;

			int count = _headers.Count;
			_grid.ColumnWidths.Clear();
			for(int i=0; i<count; i++)
			{
				_grid.ColumnWidths.Add(new GridLength());

				if (i != 0)
				{
					var columnDefinition2 = new ColumnDefinition();
					columnDefinition2.Width = new GridLength(_splitterWidth);
					columnDefinitions.Add(columnDefinition2);

					var splitter = new GridSplitter();
					splitter.ResizeBehavior = GridResizeBehavior.PreviousAndNext;
					splitter.ResizeDirection = GridResizeDirection.Columns;
					splitter.HorizontalAlignment = HorizontalAlignment.Stretch;
					splitter.VerticalAlignment = VerticalAlignment.Stretch;
					splitter.Width = _splitterWidth;
					splitter.Background = Brushes.Gray;
					Grid.SetColumn(splitter, i*2 - 1);
					headerChildren.Add(splitter);
				}

				var header = _headers[i];
				var columnDefinition = new ColumnDefinition();
				columnDefinition.MaxWidth = header.MaxWidth;
				columnDefinition.MinWidth = header.MinWidth;
				columnDefinition.Width = header.ColumnWidth;
				columnDefinitions.Add(columnDefinition);

				header._owner = this;
				header._index = i;
				Grid.SetColumn(header, i*2);
				headerChildren.Add(header);
			}
		}

		/// <summary>
		/// Gets the Children of this control.
		/// </summary>
		public UIElementCollection Children
		{
			get
			{
				return _grid.Children;
			}
		}
	}
}
